/* 更新 对象属性的时候 也需要更新对应的节点 
    . 节点的值 = 对象的属性 触发对象的引用 
    . 对象的引用 可以 把 更新的函数 放入到 通里面 
    . 设置的时候 再调用 桶里面的函数 
*/
/* 更新 对象属性的时候 也需要更新对应的节点 
    . 节点的值 = 对象的属性 触发对象的引用 
    . 对象的引用 可以 把 更新的函数 放入到 通里面 
    . 设置的时候 再调用 桶里面的函数 
*/
let activeEffect = null 
const effect =  (fn) => {
    const effectFn = () => {
        // 执行前清除工作 
        clearup(effectFn)
        activeEffect = effectFn 
        fn()
    }
    effectFn.deps = []
    effectFn()
} 
const clearup = (effectFn) => {
    for (let i = 0; i < effectFn.deps.length; i++) {
        let deps = effectFn.deps[i]
        deps.delete(effectFn)
    }
    effectFn.deps.length = 0
}
const obj = { ok: true, text: "hello, 23333" }
// weakMap key 是对象  depsMap   deps
const bucket = new WeakMap()
const data = new Proxy(obj, {
    get(target,key) { 
        if (!activeEffect) return target[key]
        // 查看依赖 
        track(target, key)
        return target[key]
    },
    set(target,key, newVale)  {
        target[key] = newVale 
        tigger(target, key)
    },
})
// 抽象出track（追踪） tigger（触发） 函数
const track = (target, key) => {
    let depsMap = bucket.get(target)
    if (!depsMap) bucket.set(target, depsMap = new Map())
    let deps = depsMap.get(key)
    if (!deps) depsMap.set(key, deps = new Set()) 
    deps.add(activeEffect)
    activeEffect.deps.push(deps)
} 
const tigger = (target, key) => {
    // 触发依赖 
    const depsMap = bucket.get(target) 
    if (!depsMap) return
    const effects = depsMap.get(key) 
    const effectsToRun = new Set(effects)
    effectsToRun && effectsToRun.forEach(effectFn => effectFn()) 
}
effect(() => { 
    console.log('effect')
    // document.body.innerHTML = data.ok ? data.text : 'false'  
})
// data.text = '测试233333'
// data.ok = false
// setTimeout(() => {
//     data.text = "hello, 23334444"
//     console.log(bucket,2333)

// }, 2000)
